<template>
  <div>
    <div class="row">
      <form @submit.prevent="connected ? disconnect() : connect()">
        <div class="form-group col-xs-12 col-sm-4">
          <div class="input-group">
            <span class="input-group-addon">ClientId</span>
            <input type="text" class="form-control" v-model="name" :readonly="connected">
          </div>
        </div>
        <div class="form-group col-xs-12 col-sm-6">
          <div class="input-group">
            <span class="input-group-addon">Server</span>
            <input type="text" class="form-control" v-model="server" :readonly="connected">
          </div>
        </div>
        <div class="col-xs-12 col-sm-2">
          <button type="submit" class="btn btn-{{connected ? 'warning' : 'success'}} btn-block">
            {{connected ? 'Disc' : 'C'}}onnect
          </button>
        </div>
      </form>
      <div class="col-xs-12 col-sm-4">
        <h4>Topic subscribed</h4>
        <div class="list-group">
          <button type="button" class="list-group-item" v-for="t in topics" @click="newMsg.topic = t">
            {{t}}
            <a href="javascript:;" class="close" @click.prevent="unsubscribe(t, $index)">
              &times;
            </a>
          </button>
          <form class="list-group-item" @submit.prevent="subscribe">
            <div class="input-group">
              <input type="text" class="form-control" v-model="newTopic" :disabled="!connected" required>
              <span class="input-group-btn">
                <button type="submit" class="btn btn-info" :disabled="!connected">
                  Add
                </button>
              </span>
            </div>
          </form>
        </div>
      </div>
      <form class="col-xs-12 col-sm-8" @submit.prevent="publish">
        <h4>Publish</h4>
        <div class="form-group">
          <div class="input-group">
            <span class="input-group-addon">Topic</span>
            <input type="text" class="form-control" v-model="newMsg.topic" :disabled="!connected" required>
          </div>
        </div>
        <div class="form-group">
          <div class="input-group">
            <span class="input-group-addon">Message</span>
            <textarea rows="3" class="form-control" v-model="newMsg.message" :disabled="!connected"></textarea>
          </div>
        </div>
        <div class="row">
          <div class="form-group col-xs-12 col-sm-6">
            <div class="input-group">
              <span class="input-group-addon">Qos</span>
              <select class="form-control" v-model="newMsg.qos" :disabled="!connected">
                <option v-for="q in [0, 1, 2]" :value="q">
                  {{q}}
                </option>
              </select>
            </div>
          </div>
          <div class="form-group col-xs-12 col-sm-3">
            <button type="button" class="btn btn-default btn-block" :disabled="!connected" @click="clear">
              Clear
            </button>
          </div>
          <div class="form-group col-xs-12 col-sm-3">
            <button type="submit" class="btn btn-info btn-block" :disabled="!connected">
              Publish
            </button>
          </div>
        </div>
      </form>
    </div>
    <h4>{{name}} Logs</h4>
    <msg :msgs="msgs"></msg>
  </div>
</template>

<script>
const Utils = require('../utils');
const each = Utils.each;
const pick = Utils.pick;
const stringify = Utils.stringify;
const isString = Utils.isString;

const Msg = require('./msg');

exports.props = [
  'mqtt',
  'name'
];

exports.components = {
  Msg
};

let lastServer = `${window.location.hostname}:8001`;
exports.data = () => {
  return {
    server: lastServer,
    connected: false,
    msgs: [],
    topics: [],
    newTopic: '',
    newMsg: {
      topic: '',
      message: '',
      qos: 0
    }
  };
};

exports.methods = {
  cmd(cmd, options) {
    return this.mqtt.publish(stringify({
      type: 'client',
      name: this.name,
      cmd
    }), stringify(options), {
      qos: 2
    });
  },
  client() {
    const topic = pick(this, [
      'name',
      'server'
    ]);
    topic.type = 'client';

    return stringify(topic);
  },
  connect() {
    const _this = this;
    _this.mqtt.subscribe(_this.client(), {
      qos: 2
    }, () => {
      _this.connected = true;

      lastServer = _this.server;
    });
  },
  disconnect() {
    const _this = this;
    _this.mqtt.unsubscribe(_this.client(), () => {
      _this.connected = false;
    });
  },
  subscribe() {
    const _this = this;
    const topic = _this.newTopic;
    _this.cmd('subscribe', {
      topic
    });
    _this.topics.push(topic);
    _this.newTopic = '';
  },
  unsubscribe(topic, index) {
    const _this = this;
    _this.cmd('unsubscribe', {
      topic
    });
    _this.topics.splice(index, 1);
  },
  publish() {
    const _this = this;
    _this.cmd('publish', _this.newMsg);
  },
  clear() {
    const _this = this;
    each(_this.newMsg, (v, k) => isString(v) && (_this.newMsg[k] = ''));
  }
};

let count = 0;
exports.created = function() {
  const _this = this;
  _this.name = `Client ${++count}`;

  _this.$on('client', (msg) => {
    if (msg.name == _this.name) {
      _this.msgs.unshift(msg);
    }
  });
};

exports.beforeDestroy = function() {
  this.disconnect();
};
</script>

<style lang="stylus">
</style>
